package com.weir.commons.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Time;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * @author huangchangjin
 * 2017年10月17日 上午9:45:26
 */
public class BaseUtil {
	private final static String  numberRE = "[0-9]*";
	private final static String  dateRE = "(\\d){4}-(\\d){2}-(\\d){2}";
	private final static String  firstImageRE = "<img[^<>]*?\\ssrc=['\"]?(.*?)['\"]?\\s.*?>";
	private final static String  nextLineRE = "\\s*|\t|\r|\n";// 换行和制表符
	private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" }; // 定义移动端请求的所有可能类型

	/**
	 * 判断User-Agent 是不是来自于手机
	 * 
	 * @param ua
	 * @return
	 */
	public static boolean checkAgentIsMobile(String ua) {
		boolean flag = false;
		if (ua == null || "".equals(ua.trim())) {
			return flag;
		}
		if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) {
			// 排除 苹果桌面系统
			if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) {
				for (String item : agent) {
					if (ua.contains(item)) {
						flag = true;
						break;
					}
				}
			}
		}
		return flag;
	}

	/**
	 * 转换成(yyyy-MM-dd)
	 * 
	 * @param ds
	 * @return
	 * @throws Exception
	 */
	public static Date parseDate(String ds) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		if (ds.indexOf("/") > 0) {
			return sdf.parse(ds.replace("/", "-"));
		} else {
			return sdf.parse(ds);
		}
	}

	/**
	 * 转换成(yyyy-MM-dd)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToString(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(d);
	}

	/**
	 * 转换成(yyyyMMdd)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringNo(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return sdf.format(d);
	}

	/**
	 * 转换成(yyyyMMddHHmmss)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringNomm(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(d);
	}

	/**
	 * 获取年份
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String year() throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yy");
		return sdf.format(new Date());
	}

	/**
	 * 获取年份
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String year(Date date) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		return sdf.format(date);
	}

	/**
	 * 获取月份
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String month(Date date) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("MM");
		return sdf.format(date);
	}

	/**
	 * 根据日期，获取时间字符串
	 * 
	 * @param date
	 * @return
	 */
	public static String getTime(Date date) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		return sdf.format(date);
	}

	/**
	 * 根据日期 找到对应天
	 */
	public static int getDay(Date date) throws Exception {
		SimpleDateFormat formatter = new SimpleDateFormat("dd");
		String str = formatter.format(date);
		return Integer.valueOf(str);
	}

	/**
	 * 根据年 月 获取对应的月份 天数
	 */
	public static int getDaysByYearMonth(int year, int month) {

		Calendar a = Calendar.getInstance();
		a.set(Calendar.YEAR, year);
		a.set(Calendar.MONTH, month - 1);
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 两个time之间的秒数<br>
	 * 例如：<br>
	 * 09:51:00和09:00:00之间的秒数
	 */
	public static long get2time(Time startTime, Time endTime) {
		return (endTime.getTime() - startTime.getTime()) / 1000;
	}

	/**
	 * Date转time<br>
	 * 例如：<br>
	 * 2017-06-01 09:51:00 转成 09:51:00
	 */
	public static Time parseDate2Time(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String timeStr = sdf.format(date);
		return Time.valueOf(timeStr);
	}

	/**
	 * 获取年月
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String yearAndMonth() throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
		return sdf.format(new Date());
	}

	/**
	 * 转换成(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringss(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(d);
	}

	/**
	 * 转换成(yyyy-MM-dd HH:mm)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringTime(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return sdf.format(d);
	}

	/**
	 * long型的数据转换成(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringss(Long l) throws Exception {
		Date date = new Date(l);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(date);
	}

	/**
	 * 转换成(MM-dd HH:mm)
	 * 
	 * @param d
	 * @return
	 * @throws Exception
	 */
	public static String parseDateToStringDateTime(Date d) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm");
		return sdf.format(d);
	}

	/**
	 * 转换成(yyyy-MM-dd HH:mm)
	 * 
	 * @param ds
	 * @return
	 * @throws Exception
	 */
	public static Date parseDateTime(String ds) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		if (ds.indexOf("/") > 0) {
			return sdf.parse(ds.replace("/", "-"));
		} else {
			return sdf.parse(ds);
		}
	}

	/**
	 * 转换成(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @param ds
	 * @return
	 * @throws Exception
	 */
	public static Date parseTimeStamp(String ds) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if (ds.indexOf("/") > 0) {
			return sdf.parse(ds.replace("/", "-"));
		} else {
			return sdf.parse(ds);
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str) {
		if (null !=str && !str.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true 大于零的
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(Long str) {
		if (null !=str && str > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(Short str) {
		if (null !=str && str > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true 大于零的
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(Double str) {
		if (null !=str && str > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true 大于零的
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(Integer str) {
		if (null !=str && str > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptyDate(Date str) {
		if (null !=str) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptyTime(Time str) {
		if (null !=str) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptySub(String[] str) {
		if (null !=str && str.length > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptySub(Integer[] str) {
		if (null !=str && str.length > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptySub(Short[] str) {
		if (null !=str && str.length > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptySub(Long[] str) {
		if (null !=str && str.length > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 不为空返回true
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptyList(Collection<?> str) {
		if (null !=str && !str.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean isEmptyMap(Map<?,?> map) {
		return (null != map && !map.isEmpty());
	}

	public static Double stringToDouble(String str) {
		if (null !=str && !str.isEmpty()) {
			return Double.valueOf(str);
		} else {
			return Double.valueOf(0);
		}
	}

	public final static Double exitAndDouble(Double d) {
		if (d != null && d > 0) {
			return d;
		} else {
			return Double.valueOf(0);
		}
	}

	public static Integer exitAndint(Integer d) {
		if (d != null && d > 0) {
			return d;
		} else {
			return Integer.valueOf(0);
		}
	}

	public static Date exitAndDate(Date d) {
		if (d != null) {
			return d;
		} else {
			return new Date();
		}
	}

	/**
	 * 不区分大小写
	 * 
	 * @param str
	 * @return
	 */
	public static String convertString(String str) {
		String upStr = str.toUpperCase();
		String lowStr = str.toLowerCase();
		StringBuffer buf = new StringBuffer(str.length());
		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == upStr.charAt(i)) {
				buf.append(lowStr.charAt(i));
			} else {
				buf.append(lowStr.charAt(i));
			}
		}
		return buf.toString();
	}

	/**
	 * 转换为大写
	 * 
	 * @param src
	 * @return
	 */
	public static String convertString1(String src) {
		char[] array = src.toCharArray();
		int temp = 0;
		for (int i = 0; i < array.length; i++) {
			temp = (int) array[i];
			if (temp <= 122 && temp >= 97) {
				array[i] = (char) (temp - 32);
			}
		}
		return String.valueOf(array);
	}

	/**
	 * double转换成String
	 * 
	 * @param str
	 * @return
	 */
	public static String doubleToString(Double str) {
		DecimalFormat df = new DecimalFormat();
		return df.format(str);
	}

	/**
	 * 数字转换成字母
	 * 
	 * @param i
	 * @return
	 */
	public static String getCha(Short i) {
		Character character = (char) (i + 64);
		return character.toString();
	}

	public static String getStringByDouble(Double d) {
		DecimalFormat df = new DecimalFormat("##0.00");
		return df.format(d);
	}

	private static final String[] beforeShuffle = new String[] { "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C",
			"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
			"Y", "Z" };

	public static String random() {
		List<String> list = Arrays.asList(beforeShuffle);
		Collections.shuffle(list);
		StringBuilder sb = new StringBuilder();
		for (int i = 0, h = list.size(); i < h; i++) {
			sb.append(list.get(i));
		}
		String afterShuffle = sb.toString();
		String result = afterShuffle.substring(5, 9);
		return result;
	}

	/**
	 * 验证邮箱
	 * 
	 * @param email
	 * @return
	 */
	public static boolean checkEmail(String email) {
		boolean flag = false;
		try {
			String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
			Pattern regex = Pattern.compile(check);
			Matcher matcher = regex.matcher(email);
			flag = matcher.matches();
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}

	/**
	 * 当前时间转换成Long(精确到秒)
	 * 
	 * @return
	 */
	public static long getNowDateToLong() {
		return System.currentTimeMillis() / 1000;
	}

	/**
	 * 大陆号码或香港号码均可
	 */
	public static boolean isPhoneLegal(String str) throws PatternSyntaxException {
		return isChinaPhoneLegal(str) || isHKPhoneLegal(str);
	}

	/**
	 * 大陆手机号码11位数，匹配格式：前三位固定格式+后8位任意数 此方法中前三位格式有： 13+任意数 15+除4的任意数 18+除1和4的任意数
	 * 17+除9的任意数 147
	 */
	public static boolean isChinaPhoneLegal(String str) throws PatternSyntaxException {
		String regExp = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-8])|(147))\\d{8}$";
		Pattern p = Pattern.compile(regExp);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 香港手机号码8位数，5|6|8|9开头+7位任意数
	 */
	public static boolean isHKPhoneLegal(String str) throws PatternSyntaxException {
		String regExp = "^(5|6|8|9)\\d{7}$";
		Pattern p = Pattern.compile(regExp);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * <p>
	 * 获取去掉"-" UUID
	 * </p>
	 */
	public static synchronized String get32UUID() {
		return UUID.randomUUID().toString().replace("-", "");
	}

	/**
	 * 判断字符串是否是正整数
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile(BaseUtil.numberRE);
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * 判断字符串日期格式 2016-01-01
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isValidDate(String date) {
		Pattern pattern = Pattern.compile(BaseUtil.dateRE);
		Matcher matcher = pattern.matcher(date);
		return matcher.find();
	}

	private final static Pattern ATTR_PATTERN = Pattern.compile(BaseUtil.firstImageRE,
			Pattern.CASE_INSENSITIVE);

	/**
	 * 获取文章里面的一个图片
	 * 
	 * @param s
	 * @return
	 */
	public static String getimg(String s) {
		Matcher matcher = ATTR_PATTERN.matcher(s);
		while (matcher.find()) {
			return matcher.group(1);
		}
		return null;
	}

	/**
	 * 提取文章里面的前50个文字
	 * 
	 * @param strHtml
	 * @return
	 */
	public static String StripHT(String strHtml) {
		// 剔出<html>的标签
		String txtcontent = strHtml.replaceAll("</?[^>]+>", ""); 
		// txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");
		// 去除字符串中的空格,回车,换行符,制表符
		Pattern p = Pattern.compile(BaseUtil.nextLineRE);
		Matcher m = p.matcher(txtcontent);
		txtcontent = m.replaceAll("");
		if (txtcontent.length() > 50) {
			return txtcontent.substring(0, 50);
		}
		return txtcontent;
	}

	/**
	 * double类型比较大小
	 * 
	 * @param d1
	 * @param d2
	 * @return 大于0：d1大，等于0：相等，小于0：d2大
	 */
	public static int doubleCompare(Double d1, Double d2) {
		d1 = exitAndDouble(d1);
		d2 = exitAndDouble(d2);
		BigDecimal b1 = new BigDecimal(d1);
		BigDecimal b2 = new BigDecimal(d2);
		return b1.compareTo(b2);
	}

	/**
	 * 提供精确的减法运算。
	 * 
	 * @param v1
	 *            被减数
	 * @param v2
	 *            减数
	 * @return 两个参数的差
	 */
	public static double doubleSub(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 从001递增到999
	 * 
	 * @author huangchangjin
	 * @param str
	 * @return
	 */
	public static String dizeng(String str) {
		int s = Integer.parseInt(str);
		s = ++s;
		s = s == 1000 ? 1 : s;
		// 计算
		String reslut = s >= 10 ? (s >= 100 ? s + "" : "0" + s) : "00" + s; 
		// 转型
		return reslut;
	}

	/**
	 * @description 判断传入的字段是否满足正则表达式
	 * @author hewei
	 * @title: chckRules
	 * @date 2017年3月27日 下午1:20:13
	 * @param regex
	 * @param str
	 * @return boolean
	 */
	public static boolean chckRulesByRegex(String regex, String str) {
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(str);
		return m.matches();
	}

	/**
	 * 百度测算距离 通过经纬度获取距离(单位：米)
	 * 
	 * @param lng1
	 *            经度 1
	 * @param lat1
	 *            纬度 1
	 * @param lng2
	 *            经度 2
	 * @param lat2
	 *            纬度 2
	 * @return
	 */
	public static double getDistanceByBaidu(double lng1, double lat1, double lng2, double lat2) {
		double radLat1 = lat1 * Math.PI / 180.0;
		double radLat2 = lat2 * Math.PI / 180.0;
		double a = radLat1 - radLat2;
		double b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
		double s = 2 * Math.asin(Math.sqrt(
				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		// 地球半径： 6378.137;
		s = s * 6378.137; 
		s = Math.round(s * 10000d) / 10000d;
		s = s * 1000;
		return s;
	}

	/**
	 * 高德测算距离 通过经纬度获取距离(单位：米)
	 * 
	 * @param lng1
	 *            经度 1
	 * @param lat1
	 *            纬度 1
	 * @param lng2
	 *            经度 2
	 * @param lat2
	 *            纬度 2
	 * @return
	 */
	public static double getDistanceByGaode(double lng1, double latitude1, double lng2, double latitude2) {
		double lon1 = (Math.PI / 180) * lng1;
		double lon2 = (Math.PI / 180) * lng2;
		double lat1 = (Math.PI / 180) * latitude1;
		double lat2 = (Math.PI / 180) * latitude2;
		// 地球半径
		double R = 6371;
		// 两点间距离 km，如果想要米的话，结果*1000就可以了
		double d = Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1))
				* R;
		return d * 1000;
	}

	/**
	 * “是或否”转换成整数
	 * 
	 * @param str
	 *            是或否
	 * @return 0否1是
	 */
	public static int getYesOrNo2Integer(String str) {
		if (null !=str && !str.isEmpty()) {
			if ("是".equals(str.trim())) {
				return 1;
			} else {
				return 0;
			}
		} else {
			return 0;
		}
	}
	/**
	 * 身份证验证
	 * @param certificateNo
	 * @return
	 */
	public static boolean checkCardNo(String certificateNo) {
		if (certificateNo.length() == 15) {
			return false;
		} else if (certificateNo.length() == 18) {
			// 6位，地区代码
			String address = certificateNo.substring(0, 6);
			// 8位，出生日期
			String birthday = certificateNo.substring(6, 14);
			// 3位，顺序码：奇为男，偶为女
//			String sequenceCode = certificateNo.substring(14, 17);
			// 1位，校验码：检验位
//			String checkCode = certificateNo.substring(17);
			String[] provinceArray = { "11:北京", "12:天津", "13:河北", "14:山西", "15:内蒙古", "21:辽宁", "22:吉林", "23:黑龙江",
					"31:上海", "32:江苏", "33:浙江", "34:安徽", "35:福建", "36:江西", "37:山东", "41:河南", "42:湖北 ", "43:湖南", "44:广东",
					"45:广西", "46:海南", "50:重庆", "51:四川", "52:贵州", "53:云南", "54:西藏 ", "61:陕西", "62:甘肃", "63:青海", "64:宁夏",
					"65:新疆", "71:台湾", "81:香港", "82:澳门", "91:国外" };
			boolean valideAddress = false;
			for (int i = 0; i < provinceArray.length; i++) {
				String provinceKey = provinceArray[i].split(":")[0];
				if (provinceKey.equals(address.substring(0, 2))) {
					valideAddress = true;
				}
			}
			if (valideAddress) {
				String year = birthday.substring(0, 4);
				String month = birthday.substring(4, 6);
				String day = birthday.substring(6);
				Calendar cal = Calendar.getInstance();
				cal.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));
				Date tempDate = cal.getTime();
				Calendar cal2=Calendar.getInstance();  
				cal2.setTime(tempDate);  
				if ((cal2.get(Calendar.YEAR) != Integer.parseInt(year) || cal2.get(Calendar.MONTH) != Integer.parseInt(month) - 1
						|| cal2.get(Calendar.DAY_OF_MONTH) != Integer.parseInt(day))) {
					// 避免千年虫问题
					return false;
				} else {
					// 加权因子
					int[] weightedFactors = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
					// 身份证验证位值，其中10代表X
					int[] valideCode = { 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
					// 声明加权求和变量
					int sum = 0;
					String[] certificateNoArray = new String[certificateNo.length()];
					for (int i = 0; i < certificateNo.length(); i++) {
						certificateNoArray[i] = String.valueOf(certificateNo.charAt(i));
					}
					if ("x".equals(certificateNoArray[17].toLowerCase())) {
						// 将最后位为x的验证码替换为10
						certificateNoArray[17] = "10";
					}
					for (int i = 0; i < 17; i++) {
						// 加权求和
						sum += weightedFactors[i] * Integer.parseInt(certificateNoArray[i]);
					}
					// 得到验证码所在位置
					int valCodePosition = sum % 11;
					if (Integer.parseInt(certificateNoArray[17]) == valideCode[valCodePosition]) {
						return true;
					} else {
						return false;
					}
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	 * 生成一位指定长度的随机数字
	 * @return
	 */
	public static String randomRandomCode(int codeLength) {
		Random rand = new Random();
		String result = "";
		for(int i=0; i<codeLength; i++) {
			result += rand.nextInt(10);
		}
		return result;
	}
	
    /** 
     * 替换指定标签的属性和值 
     * @param str 需要处理的字符串 
     * @param tag 标签名称 
     * @param tagAttrib 要替换的标签属性值 
     * @param startTag 新标签开始标记 
     * @param endTag  新标签结束标记 
     * @return 
     * @author huweijun 
     * @date 2016年7月13日 下午7:15:32 
     */  
    public static String replaceHtmlTag(String str, String tag, String tagAttrib, String startTag, String endTag) {  
        String regxpForTag = "<\\s*" + tag + "\\s+([^>]*)\\s*" ;  
        String regxpForTagAttrib = tagAttrib + "=\\s*\"([^\"]+)\"" ;  
        Pattern patternForTag = Pattern.compile (regxpForTag,Pattern. CASE_INSENSITIVE );  
        Pattern patternForAttrib = Pattern.compile (regxpForTagAttrib,Pattern. CASE_INSENSITIVE );     
        Matcher matcherForTag = patternForTag.matcher(str);  
        StringBuffer sb = new StringBuffer();  
        boolean result = matcherForTag.find();  
        while (result) {  
            StringBuffer sbreplace = new StringBuffer( "<"+tag+" ");  
            Matcher matcherForAttrib = patternForAttrib.matcher(matcherForTag.group(1));  
            if (matcherForAttrib.find()) {  
                String attributeStr = matcherForAttrib.group(1);  
                matcherForAttrib.appendReplacement(sbreplace, startTag + attributeStr + endTag);  
            }  
            matcherForAttrib.appendTail(sbreplace);  
            matcherForTag.appendReplacement(sb, sbreplace.toString());  
            result = matcherForTag.find();  
        }  
        matcherForTag.appendTail(sb);           
        return sb.toString();  
    }
    /**
	 * 字符串每个字符封装成一个list
	 * @param str 字符串
	 * @return list集合
	 */
	public static List<String> stringToList(String str) {
		List<String> list = new ArrayList<>();
		for (int i = 0; i < str.length(); i++) {  
            int cp = str.codePointAt(i);  
            if (!Character.isSupplementaryCodePoint(cp)) {  
                list.add(String.valueOf((char) cp));
            } else {  
                list.add(String.valueOf(cp));
                i++;  
            }  
        }
		return list;
	}
	
	/**   
     * 将元为单位的转换为分 （乘100）  
     *   
     * @param amount  
     * @return  
     */    
    public static String changeY2F(Double amount){
        return BigDecimal.valueOf(amount).multiply(new BigDecimal(100)).toString();
    }
        
    /**   
     * 将元为单位的转换为分 替换小数点，支持以逗号区分的金额  
     *   
     * @param amount  
     * @return  
     */    
    public static String changeY2F(String amount){
        String currency =  amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额    
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if(index == -1){
            amLong = Long.valueOf(currency+"00");
        }else if(length - index >= 3){
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));
        }else if(length - index == 2){
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);
        }else{
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");
        }
        return amLong.toString();
    }
    /**金额为分的格式 */
    public static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+";
    /**   
     * 将分为单位的转换为元并返回金额格式的字符串 （除100）  
     *   
     * @param amount  
     * @return  
     * @throws Exception   
     */    
    public static String changeF2Y(Double amount) throws Exception{
        if(!amount.toString().matches(CURRENCY_FEN_REGEX)) {
            throw new Exception("金额格式有误");
        }
        int flag = 0;
        String amString = amount.toString();
        if(amString.charAt(0)=='-'){
            flag = 1;
            amString = amString.substring(1);
        }
        StringBuffer result = new StringBuffer();
        if(amString.length()==1){
            result.append("0.0").append(amString);
        }else if(amString.length() == 2){
            result.append("0.").append(amString);
        }else{
            String intString = amString.substring(0,amString.length()-2);
            for(int i=1; i<=intString.length();i++){
                if( (i-1)%3 == 0 && i !=1){
                    result.append(",");
                }
                result.append(intString.substring(intString.length()-i,intString.length()-i+1));
            }
            result.reverse().append(".").append(amString.substring(amString.length()-2));
        }
        if(flag == 1){
            return "-"+result.toString();
        }else{
            return result.toString();
        }
    }
    /**  
     * 将分为单位的转换为元 （除100）  
     *   
     * @param amount  
     * @return  
     * @throws Exception   
     */    
    public static String changeF2Y(String amount) throws Exception{
        if(!amount.matches(CURRENCY_FEN_REGEX)) {
            throw new Exception("金额格式有误");
        }
        return BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)).toString();
    }
    
    public static Date dateBefor(Date date) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	calendar.add(Calendar.DAY_OF_MONTH, -1);
    	return calendar.getTime(); 
	}
    
    public static String randomNum() {
    	return ((Double)((Math.random()*9+1)*10000000)).toString();
	}
	
	/**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }
    
    /**
	 * 将逗号分隔的整数字符串转换成list
	 *
	 * @param str 需转换字符
	 * @return
	 */
	public static List<Integer> string2List(String str) {
		if (!isEmpty(str)) {
			return null;
		}
		StringTokenizer st = new StringTokenizer(str, ",");
		List<Integer> list = new ArrayList<>();
		while (st.hasMoreElements()) {
			list.add(Integer.valueOf(st.nextToken().trim()));
		}
		return list;
	}

	/**
	 * 获取百分比
	 *
	 * @param divisor  除数
	 * @param dividend 被除数
	 * @param mun      保留几位小数
	 * @return string百分比
	 */
	public static String getPercent(double divisor, double dividend, int mun) {
		if (dividend == 0) {
			return null;
		}
		NumberFormat nt = NumberFormat.getPercentInstance();
		// 设置百分数精确度2即保留两位小数
		nt.setMinimumFractionDigits(mun);
		return nt.format(divisor / dividend);
	}

	/**
	 * 将map里面value以逗号分隔的字符串转List
	 *
	 * @param map     map
	 * @param mapKeys kay
	 * @return list
	 */
	public static Map<String, Object> getMapForDelimitedToStringList(
			Map<String, Object> map, String... mapKeys) {
		if (!isEmptyMap(map)) {
			return map;
		}
		for (String key : mapKeys) {
			if (map.get(key) instanceof String) {
				List<String> list = Arrays
						.asList(map.get(key).toString().split(","));
				map.put(key, list);
			}
		}
		return map;
	}

	/**
	 * 以逗号分隔的字符串转List
	 *
	 * @param str
	 * @return
	 */
	public static List<String> commaDelimitedToStringList(String str) {
		if (!isEmpty(str)) {
			return null;
		}
		return Arrays.asList(str.split(","));
	}

	/**
	 * 字符串去掉首尾字符
	 * 
	 * @param str 字符串
	 * @return 字符串
	 */
	public static String delFirstEnd(String str) {
		return str.substring(1, str.length() - 1);
	}

	/**
	 * bean 转化为 map
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> tranferBean2Map(Object obj) {
		// obj为空，结束方法
		if (obj == null)
			return null;
		Map<String, Object> map = new HashMap<String, Object>();
		/*
		 * Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
		 * java的自省机制
		 */
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor propertyDescriptor : ps) {
				String key = propertyDescriptor.getName();

				if (!"class".equals(key)) {
					Method getter = propertyDescriptor.getReadMethod();
					Object value = getter.invoke(obj);
					map.put(key, value);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException("parse " + obj + " error");
		}
		return map;

	}

	/**
	 * 整数相除(保留两位)
	 * 
	 * @param a 被除数
	 * @param b 除数
	 * @param m 保留位数
	 * @return
	 */
	public static double txfloat(int a, int b ,int m) {
		if (b == 0) {
			return 0;
		}
		return new BigDecimal(((float) a / b) * 100)
				.setScale(m, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 降序排序
	 * 
	 * @param map map
	 * @return map
	 */
	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDescending(
			Map<K, V> map) {
		List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(
				map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
			@Override
			public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
				int compare = (o1.getValue()).compareTo(o2.getValue());
				return -compare;
			}
		});

		Map<K, V> result = new LinkedHashMap<K, V>();
		for (Map.Entry<K, V> entry : list) {
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}

	/**
	 * 升序排序
	 * 
	 * @param map map
	 * @return map
	 */
	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAscending(
			Map<K, V> map) {
		List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(
				map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
			@Override
			public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
				int compare = (o1.getValue()).compareTo(o2.getValue());
				return compare;
			}
		});

		Map<K, V> result = new LinkedHashMap<K, V>();
		for (Map.Entry<K, V> entry : list) {
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}
	
	/**
	 * 计算2个日期相差多少年
	 * 列：2011-02-02  ~  2017-03-02 大约相差 6.1 年
	 * @param fromDate
	 * @param toDate
	 * @return
	 */
	public static String yearCompare(Date fromDate,Date toDate){
		Calendar  from  =  Calendar.getInstance();
	    from.setTime(fromDate);
	    Calendar  to  =  Calendar.getInstance();
	    to.setTime(toDate);

	    int fromYear = from.get(Calendar.YEAR);
	    int fromMonth = from.get(Calendar.MONTH);

	    int toYear = to.get(Calendar.YEAR);
	    int toMonth = to.get(Calendar.MONTH);
	    int year = toYear  -  fromYear;
	    int month = toMonth  - fromMonth;
	    //返回2位小数，并且四舍五入
	    DecimalFormat df = new DecimalFormat("######0.0");
	    return df.format(year + month / 12);
	}
	/**
	 * double保留几位小数
	 * @param d 原书
	 * @param m 保留几位
	 * @return
	 */
	public static double keepDecimal(Double d,Integer m) {
		if (!isEmpty(m)) {
			return 0;
		}
		BigDecimal b = new BigDecimal(d);
		return b.setScale(m, BigDecimal.ROUND_HALF_UP).doubleValue();   
	}
	
    public static void main(String[] args) {
		System.out.println(changeY2F("2.01"));
		try {
			System.out.println(changeF2Y("201"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
